package com.knowledgeqa.system.filter;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.knowledgeqa.system.entity.User;
import com.knowledgeqa.system.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.*;
import java.io.*;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Pattern;

/**
 *
 *
 * 1.综合过滤器系统
 * 2.包含身份验证、权限控制、安全防护、日志记录、性能监控等多种功能
 * 3.用于保护知识问答系统的核心功能
 */
@WebFilter(urlPatterns = {"/*"})
@Order(1)
@Component
@Configuration
public class filter extends OncePerRequestFilter {

    // 注入用户服务
    @Autowired
    private UserService userService;

    // 存储用户会话信息
    private static final Map<String, UserSession> userSessions = new ConcurrentHashMap<>();

    // 存储IP访问频率信息
    private static final Map<String, AtomicInteger> ipAccessCount = new ConcurrentHashMap<>();

    // 存储用户访问频率信息
    private static final Map<Long, AtomicInteger> userAccessCount = new ConcurrentHashMap<>();

    // 存储黑名单IP
    private static final Set<String> blacklistedIps = ConcurrentHashMap.newKeySet();

    // 存储敏感词库
    private static final Set<String> sensitiveWords = ConcurrentHashMap.newKeySet();

    // 存储请求统计信息
    private static final Map<String, RequestStats> requestStats = new ConcurrentHashMap<>();

    // 存储API访问统计
    private static final Map<String, ApiAccessStats> apiAccessStats = new ConcurrentHashMap<>();

    // 存储异常请求记录
    private static final List<SecurityLog> securityLogs = Collections.synchronizedList(new ArrayList<>());

    // 存储用户登录失败记录
    private static final Map<String, LoginAttempt> loginAttempts = new ConcurrentHashMap<>();

    // 存储会话创建时间
    private static final Map<String, Long> sessionCreationTime = new ConcurrentHashMap<>();

    // 存储文件上传记录
    private static final Map<String, UploadRecord> uploadRecords = new ConcurrentHashMap<>();

    // 存储SQL注入检测模式
    private static final List<Pattern> sqlInjectionPatterns = new ArrayList<>();

    // 存储XSS攻击检测模式
    private static final List<Pattern> xssPatterns = new ArrayList<>();

    // 存储CSRF Token
    private static final Map<String, String> csrfTokens = new ConcurrentHashMap<>();

    // 存储API速率限制
    private static final Map<String, RateLimitInfo> rateLimits = new ConcurrentHashMap<>();

    // 系统配置参数
    private static final int MAX_LOGIN_ATTEMPTS = 5;
    private static final long LOGIN_LOCKOUT_DURATION = 30 * 60 * 1000; // 30分钟
    private static final int MAX_REQUESTS_PER_MINUTE = 100;
    private static final int MAX_UPLOAD_SIZE = 10 * 1024 * 1024; // 10MB
    private static final long SESSION_TIMEOUT = 30 * 60 * 1000; // 30分钟
    private static final String[] PROTECTED_PATHS = {
            "/api/user/update",
            "/api/user/avatar",
            "/api/question/create",
            "/api/answer/create",
            "/admin"
    };

    // 初始化安全模式
    static {
        // SQL注入检测模式
        sqlInjectionPatterns.add(Pattern.compile("(?i)(union|select|insert|update|delete|drop|create|alter|exec|execute)"));
        sqlInjectionPatterns.add(Pattern.compile("(?i)(\\b(\\w*)\\s*\\=\\s*\\1\\b)"));
        sqlInjectionPatterns.add(Pattern.compile("(?i)(\\b(\\w*)\\s*like\\s*\\1\\b)"));
        sqlInjectionPatterns.add(Pattern.compile("(?i)([\\s]*or[\\s]*[\\d]+[\\s]*=[\\s]*[\\d]+)"));

        // XSS攻击检测模式
        xssPatterns.add(Pattern.compile("(?i)(<script|javascript:|vbscript:|onload|onerror)"));
        xssPatterns.add(Pattern.compile("(?i)(alert\\(|eval\\(|document\\.|window\\.)"));
        xssPatterns.add(Pattern.compile("(?i)(expression\\(|url\\(|data:|base64)"));
        xssPatterns.add(Pattern.compile("(?i)(<iframe|<object|<embed|<applet)"));

        // 初始化敏感词库
        sensitiveWords.add("fuck");
        sensitiveWords.add("shit");
        sensitiveWords.add("damn");
        sensitiveWords.add("asshole");
        sensitiveWords.add("bitch");
    }

    /**
     * 主要的过滤方法，处理所有HTTP请求
     *
     * @param request  HTTP请求对象
     * @param response HTTP响应对象
     * @param chain    过滤器链
     * @throws IOException      IO异常
     * @throws ServletException Servlet异常
     */
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
            throws IOException, ServletException {

        // 记录请求开始时间
        long startTime = System.currentTimeMillis();

        // 获取请求相关信息
        String requestURI = request.getRequestURI();
        String clientIP = getClientIP(request);
        String method = request.getMethod();
        String userAgent = request.getHeader("User-Agent");

        // 初始化用户服务（如果尚未注入）
        initUserService(request);

        try {
            // 记录请求日志
            logRequest(request, clientIP);

            // 检查IP是否在黑名单中
            if (isBlacklistedIP(clientIP)) {
                handleBlockedRequest(request, response, "IP黑名单拦截");
                return;
            }

            // 检查请求频率限制
            if (isRateLimited(clientIP, requestURI)) {
                handleRateLimitExceeded(request, response);
                return;
            }

            // 检查是否为恶意请求
            if (isMaliciousRequest(request)) {
                handleMaliciousRequest(request, response);
                return;
            }

            // 检查登录尝试次数
            if (isLoginLockedOut(clientIP)) {
                handleLoginLockout(request, response);
                return;
            }

            // 检查会话是否过期
            if (isSessionExpired(request)) {
                handleSessionExpired(request, response);
            }

            // 处理特定路径的安全检查
            if (requiresAuthentication(requestURI)) {
                if (!isAuthenticated(request)) {
                    handleUnauthenticatedRequest(request, response);
                    return;
                }

                // 检查权限
                if (!hasPermission(request)) {
                    handleUnauthorizedRequest(request, response);
                    return;
                }
            }

            // 处理文件上传安全检查
            if (isFileUploadRequest(request)) {
                if (!isSafeFileUpload(request)) {
                    handleUnsafeFileUpload(request, response);
                    return;
                }
            }

            // 处理CSRF防护
            if (requiresCSRFProtection(request)) {
                if (!validateCSRFToken(request)) {
                    handleCSRFViolation(request, response);
                    return;
                }
            }

            // 更新访问统计
            updateAccessStats(requestURI, clientIP, method);

            // 继续执行过滤器链
            chain.doFilter(request, response);

        } catch (Exception e) {
            // 记录异常
            logSecurityEvent(clientIP, "FILTER_EXCEPTION", e.getMessage());
            throw e;
        } finally {
            // 记录响应时间和统计信息
            long endTime = System.currentTimeMillis();
            recordRequestStats(requestURI, endTime - startTime);
        }
    }

    /**
     * 初始化用户服务
     *
     * @param request HTTP请求对象
     */
    private void initUserService(HttpServletRequest request) {
        if (userService == null) {
            ServletContext servletContext = request.getServletContext();
            WebApplicationContext webApplicationContext = WebApplicationContextUtils.getWebApplicationContext(servletContext);
            if (webApplicationContext != null) {
                userService = webApplicationContext.getBean(UserService.class);
            }
        }
    }

    /**
     * 获取客户端真实IP地址
     *
     * @param request HTTP请求对象
     * @return 客户端IP地址
     */
    private String getClientIP(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("X-Real-IP");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
            if ("0:0:0:0:0:0:0:1".equals(ip)) {
                ip = "127.0.0.1";
            }
        }

        // 处理多个IP的情况（多个代理）
        if (ip != null && ip.contains(",")) {
            ip = ip.split(",")[0];
        }

        return ip;
    }

    /**
     * 记录请求日志
     *
     * @param request HTTP请求对象
     * @param clientIP 客户端IP地址
     */
    private void logRequest(HttpServletRequest request, String clientIP) {
        String requestURI = request.getRequestURI();
        String method = request.getMethod();
        String queryString = request.getQueryString();
        String userAgent = request.getHeader("User-Agent");

        // 记录到控制台
        System.out.println(String.format("[%s] %s %s %s %s",
                getCurrentTime(),
                clientIP,
                method,
                requestURI + (queryString != null ? "?" + queryString : ""),
                userAgent));

        // 记录到安全日志
        logSecurityEvent(clientIP, "REQUEST", method + " " + requestURI);
    }

    /**
     * 获取当前时间字符串
     *
     * @return 当前时间格式化字符串
     */
    private String getCurrentTime() {
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
    }

    /**
     * 检查IP是否在黑名单中
     *
     * @param ip IP地址
     * @return 是否在黑名单中
     */
    private boolean isBlacklistedIP(String ip) {
        return blacklistedIps.contains(ip);
    }

    /**
     * 处理被阻止的请求
     *
     * @param request HTTP请求对象
     * @param response HTTP响应对象
     * @param reason 阻止原因
     * @throws IOException IO异常
     */
    private void handleBlockedRequest(HttpServletRequest request, HttpServletResponse response, String reason)
            throws IOException {
        String clientIP = getClientIP(request);
        logSecurityEvent(clientIP, "BLOCKED_REQUEST", reason);

        response.setStatus(HttpStatus.FORBIDDEN.value());
        response.setContentType("application/json;charset=UTF-8");

        Map<String, Object> result = new HashMap<>();
        result.put("success", false);
        result.put("message", "请求被拒绝: " + reason);

        ObjectMapper mapper = new ObjectMapper();
        response.getWriter().write(mapper.writeValueAsString(result));
    }

    /**
     * 检查请求频率限制
     *
     * @param ip IP地址
     * @param requestURI 请求URI
     * @return 是否超过频率限制
     */
    private boolean isRateLimited(String ip, String requestURI) {
        // 更新IP访问计数
        AtomicInteger ipCount = ipAccessCount.computeIfAbsent(ip, k -> new AtomicInteger(0));
        int currentIpCount = ipCount.incrementAndGet();

        // 检查API速率限制
        String rateLimitKey = ip + ":" + requestURI;
        RateLimitInfo rateLimitInfo = rateLimits.computeIfAbsent(rateLimitKey,
                k -> new RateLimitInfo(System.currentTimeMillis(), 1));

        long currentTime = System.currentTimeMillis();
        if (currentTime - rateLimitInfo.getLastRequestTime() > 60000) { // 1分钟窗口
            rateLimitInfo.reset(currentTime);
        } else {
            rateLimitInfo.increment();
        }

        return currentIpCount > MAX_REQUESTS_PER_MINUTE ||
                rateLimitInfo.getRequestCount() > MAX_REQUESTS_PER_MINUTE / 10;
    }

    /**
     * 处理频率限制超限
     *
     * @param request HTTP请求对象
     * @param response HTTP响应对象
     * @throws IOException IO异常
     */
    private void handleRateLimitExceeded(HttpServletRequest request, HttpServletResponse response)
            throws IOException {
        String clientIP = getClientIP(request);
        logSecurityEvent(clientIP, "RATE_LIMIT_EXCEEDED", "请求频率超限");

        response.setStatus(HttpStatus.TOO_MANY_REQUESTS.value());
        response.setContentType("application/json;charset=UTF-8");

        Map<String, Object> result = new HashMap<>();
        result.put("success", false);
        result.put("message", "请求过于频繁，请稍后再试");

        ObjectMapper mapper = new ObjectMapper();
        response.getWriter().write(mapper.writeValueAsString(result));
    }

    /**
     * 检查是否为恶意请求
     *
     * @param request HTTP请求对象
     * @return 是否为恶意请求
     */
    private boolean isMaliciousRequest(HttpServletRequest request) {
        String requestURI = request.getRequestURI();
        String queryString = request.getQueryString();
        String method = request.getMethod();

        // 检查SQL注入
        if (containsSQLInjection(requestURI) ||
                (queryString != null && containsSQLInjection(queryString))) {
            return true;
        }

        // 检查XSS攻击
        if (containsXSS(requestURI) ||
                (queryString != null && containsXSS(queryString))) {
            return true;
        }

        // 检查敏感词
        if (containsSensitiveWords(requestURI) ||
                (queryString != null && containsSensitiveWords(queryString))) {
            return true;
        }

        return false;
    }

    /**
     * 检查是否包含SQL注入
     *
     * @param input 输入字符串
     * @return 是否包含SQL注入
     */
    private boolean containsSQLInjection(String input) {
        if (input == null) return false;

        for (Pattern pattern : sqlInjectionPatterns) {
            if (pattern.matcher(input).find()) {
                return true;
            }
        }
        return false;
    }

    /**
     * 检查是否包含XSS攻击
     *
     * @param input 输入字符串
     * @return 是否包含XSS攻击
     */
    private boolean containsXSS(String input) {
        if (input == null) return false;

        for (Pattern pattern : xssPatterns) {
            if (pattern.matcher(input).find()) {
                return true;
            }
        }
        return false;
    }

    /**
     * 检查是否包含敏感词
     *
     * @param input 输入字符串
     * @return 是否包含敏感词
     */
    private boolean containsSensitiveWords(String input) {
        if (input == null) return false;

        String lowerInput = input.toLowerCase();
        for (String word : sensitiveWords) {
            if (lowerInput.contains(word)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 处理恶意请求
     *
     * @param request HTTP请求对象
     * @param response HTTP响应对象
     * @throws IOException IO异常
     */
    private void handleMaliciousRequest(HttpServletRequest request, HttpServletResponse response)
            throws IOException {
        String clientIP = getClientIP(request);
        logSecurityEvent(clientIP, "MALICIOUS_REQUEST", "检测到恶意请求");

        // 将IP加入黑名单
        blacklistedIps.add(clientIP);

        response.setStatus(HttpStatus.BAD_REQUEST.value());
        response.setContentType("application/json;charset=UTF-8");

        Map<String, Object> result = new HashMap<>();
        result.put("success", false);
        result.put("message", "请求包含非法内容");

        ObjectMapper mapper = new ObjectMapper();
        response.getWriter().write(mapper.writeValueAsString(result));
    }

    /**
     * 检查登录是否被锁定
     *
     * @param ip IP地址
     * @return 是否被锁定
     */
    private boolean isLoginLockedOut(String ip) {
        LoginAttempt attempt = loginAttempts.get(ip);
        if (attempt != null) {
            long currentTime = System.currentTimeMillis();
            if (attempt.getAttempts() >= MAX_LOGIN_ATTEMPTS &&
                    currentTime - attempt.getLastAttemptTime() < LOGIN_LOCKOUT_DURATION) {
                return true;
            }
        }
        return false;
    }

    /**
     * 处理登录锁定
     *
     * @param request HTTP请求对象
     * @param response HTTP响应对象
     * @throws IOException IO异常
     */
    private void handleLoginLockout(HttpServletRequest request, HttpServletResponse response)
            throws IOException {
        String clientIP = getClientIP(request);
        logSecurityEvent(clientIP, "LOGIN_LOCKOUT", "登录尝试次数超限");

        response.setStatus(HttpStatus.TOO_MANY_REQUESTS.value());
        response.setContentType("application/json;charset=UTF-8");

        Map<String, Object> result = new HashMap<>();
        result.put("success", false);
        result.put("message", "登录失败次数过多，请30分钟后再试");

        ObjectMapper mapper = new ObjectMapper();
        response.getWriter().write(mapper.writeValueAsString(result));
    }

    /**
     * 检查会话是否过期
     *
     * @param request HTTP请求对象
     * @return 是否过期
     */
    private boolean isSessionExpired(HttpServletRequest request) {
        HttpSession session = request.getSession(false);
        if (session != null) {
            String sessionId = session.getId();
            Long creationTime = sessionCreationTime.get(sessionId);
            if (creationTime != null) {
                long currentTime = System.currentTimeMillis();
                return (currentTime - creationTime) > SESSION_TIMEOUT;
            }
        }
        return false;
    }

    /**
     * 处理会话过期
     *
     * @param request HTTP请求对象
     * @param response HTTP响应对象
     * @throws IOException IO异常
     */
    private void handleSessionExpired(HttpServletRequest request, HttpServletResponse response)
            throws IOException {
        HttpSession session = request.getSession(false);
        if (session != null) {
            session.invalidate();
        }

        logSecurityEvent(getClientIP(request), "SESSION_EXPIRED", "会话已过期");

        response.setStatus(HttpStatus.UNAUTHORIZED.value());
        response.setContentType("application/json;charset=UTF-8");

        Map<String, Object> result = new HashMap<>();
        result.put("success", false);
        result.put("message", "会话已过期，请重新登录");

        ObjectMapper mapper = new ObjectMapper();
        response.getWriter().write(mapper.writeValueAsString(result));
    }

    /**
     * 检查路径是否需要身份验证
     *
     * @param requestURI 请求URI
     * @return 是否需要身份验证
     */
    private boolean requiresAuthentication(String requestURI) {
        for (String path : PROTECTED_PATHS) {
            if (requestURI.startsWith(path)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 检查用户是否已认证
     *
     * @param request HTTP请求对象
     * @return 是否已认证
     */
    private boolean isAuthenticated(HttpServletRequest request) {
        HttpSession session = request.getSession(false);
        if (session != null) {
            String sessionId = session.getId();
            UserSession userSession = userSessions.get(sessionId);
            return userSession != null && userSession.getUser() != null;
        }
        return false;
    }

    /**
     * 处理未认证请求
     *
     * @param request HTTP请求对象
     * @param response HTTP响应对象
     * @throws IOException IO异常
     */
    private void handleUnauthenticatedRequest(HttpServletRequest request, HttpServletResponse response)
            throws IOException {
        logSecurityEvent(getClientIP(request), "UNAUTHENTICATED_ACCESS", "未认证访问受保护资源");

        response.setStatus(HttpStatus.UNAUTHORIZED.value());
        response.setContentType("application/json;charset=UTF-8");

        Map<String, Object> result = new HashMap<>();
        result.put("success", false);
        result.put("message", "请先登录");

        ObjectMapper mapper = new ObjectMapper();
        response.getWriter().write(mapper.writeValueAsString(result));
    }

    /**
     * 检查用户权限
     *
     * @param request HTTP请求对象
     * @return 是否有权限
     */
    private boolean hasPermission(HttpServletRequest request) {
        HttpSession session = request.getSession(false);
        if (session != null) {
            String sessionId = session.getId();
            UserSession userSession = userSessions.get(sessionId);
            if (userSession != null) {
                User user = userSession.getUser();
                String requestURI = request.getRequestURI();

                // 管理员路径需要管理员权限
                if (requestURI.startsWith("/admin")) {
                    return user.getRole() != null && user.getRole() == 1; // 1表示管理员
                }

                // 其他受保护路径需要登录即可
                return true;
            }
        }
        return false;
    }

    /**
     * 处理未授权请求
     *
     * @param request HTTP请求对象
     * @param response HTTP响应对象
     * @throws IOException IO异常
     */
    private void handleUnauthorizedRequest(HttpServletRequest request, HttpServletResponse response)
            throws IOException {
        logSecurityEvent(getClientIP(request), "UNAUTHORIZED_ACCESS", "权限不足");

        response.setStatus(HttpStatus.FORBIDDEN.value());
        response.setContentType("application/json;charset=UTF-8");

        Map<String, Object> result = new HashMap<>();
        result.put("success", false);
        result.put("message", "权限不足");

        ObjectMapper mapper = new ObjectMapper();
        response.getWriter().write(mapper.writeValueAsString(result));
    }

    /**
     * 检查是否为文件上传请求
     *
     * @param request HTTP请求对象
     * @return 是否为文件上传请求
     */
    private boolean isFileUploadRequest(HttpServletRequest request) {
        String contentType = request.getContentType();
        return contentType != null && contentType.toLowerCase().startsWith("multipart/");
    }

    /**
     * 检查文件上传是否安全
     *
     * @param request HTTP请求对象
     * @return 是否安全
     */
    private boolean isSafeFileUpload(HttpServletRequest request) {
        // 这里可以添加更详细的文件上传安全检查
        // 例如：文件类型检查、文件大小检查、文件名检查等
        return true;
    }

    /**
     * 处理不安全的文件上传
     *
     * @param request HTTP请求对象
     * @param response HTTP响应对象
     * @throws IOException IO异常
     */
    private void handleUnsafeFileUpload(HttpServletRequest request, HttpServletResponse response)
            throws IOException {
        logSecurityEvent(getClientIP(request), "UNSAFE_FILE_UPLOAD", "不安全的文件上传");

        response.setStatus(HttpStatus.BAD_REQUEST.value());
        response.setContentType("application/json;charset=UTF-8");

        Map<String, Object> result = new HashMap<>();
        result.put("success", false);
        result.put("message", "文件上传不安全");

        ObjectMapper mapper = new ObjectMapper();
        response.getWriter().write(mapper.writeValueAsString(result));
    }

    /**
     * 检查是否需要CSRF保护
     *
     * @param request HTTP请求对象
     * @return 是否需要CSRF保护
     */
    private boolean requiresCSRFProtection(HttpServletRequest request) {
        String method = request.getMethod();
        return "POST".equalsIgnoreCase(method) ||
                "PUT".equalsIgnoreCase(method) ||
                "DELETE".equalsIgnoreCase(method);
    }

    /**
     * 验证CSRF Token
     *
     * @param request HTTP请求对象
     * @return Token是否有效
     */
    private boolean validateCSRFToken(HttpServletRequest request) {
        String token = request.getHeader("X-CSRF-TOKEN");
        if (token == null) {
            token = request.getParameter("_csrf");
        }

        if (token != null) {
            HttpSession session = request.getSession(false);
            if (session != null) {
                String sessionId = session.getId();
                String expectedToken = csrfTokens.get(sessionId);
                return expectedToken != null && expectedToken.equals(token);
            }
        }
        return false;
    }

    /**
     * 处理CSRF违规
     *
     * @param request HTTP请求对象
     * @param response HTTP响应对象
     * @throws IOException IO异常
     */
    private void handleCSRFViolation(HttpServletRequest request, HttpServletResponse response)
            throws IOException {
        logSecurityEvent(getClientIP(request), "CSRF_VIOLATION", "CSRF Token验证失败");

        response.setStatus(HttpStatus.FORBIDDEN.value());
        response.setContentType("application/json;charset=UTF-8");

        Map<String, Object> result = new HashMap<>();
        result.put("success", false);
        result.put("message", "请求验证失败");

        ObjectMapper mapper = new ObjectMapper();
        response.getWriter().write(mapper.writeValueAsString(result));
    }

    /**
     * 更新访问统计
     *
     * @param requestURI 请求URI
     * @param clientIP 客户端IP
     * @param method HTTP方法
     */
    private void updateAccessStats(String requestURI, String clientIP, String method) {
        // 更新请求统计
        RequestStats stats = requestStats.computeIfAbsent(requestURI, k -> new RequestStats());
        stats.incrementCount();

        // 更新API访问统计
        String apiStatsKey = method + ":" + requestURI;
        ApiAccessStats apiStats = apiAccessStats.computeIfAbsent(apiStatsKey, k -> new ApiAccessStats());
        apiStats.incrementAccessCount();
        apiStats.addClientIP(clientIP);
    }

    /**
     * 记录请求统计信息
     *
     * @param requestURI 请求URI
     * @param responseTime 响应时间（毫秒）
     */
    private void recordRequestStats(String requestURI, long responseTime) {
        RequestStats stats = requestStats.get(requestURI);
        if (stats != null) {
            stats.addResponseTime(responseTime);
        }
    }

    /**
     * 记录安全事件
     *
     * @param ip IP地址
     * @param eventType 事件类型
     * @param description 事件描述
     */
    private void logSecurityEvent(String ip, String eventType, String description) {
        SecurityLog log = new SecurityLog();
        log.setTimestamp(System.currentTimeMillis());
        log.setIp(ip);
        log.setEventType(eventType);
        log.setDescription(description);
        securityLogs.add(log);

        // 控制日志数量，避免内存溢出
        if (securityLogs.size() > 10000) {
            synchronized (securityLogs) {
                if (securityLogs.size() > 10000) {
                    securityLogs.subList(0, 5000).clear();
                }
            }
        }
    }

    /**
     * 用户登录成功处理
     *
     * @param user 用户对象
     * @param request HTTP请求对象
     */
    public static void onUserLoginSuccess(User user, HttpServletRequest request) {
        HttpSession session = request.getSession(true);
        String sessionId = session.getId();

        // 创建用户会话
        UserSession userSession = new UserSession();
        userSession.setUser(user);
        userSession.setLoginTime(System.currentTimeMillis());
        userSessions.put(sessionId, userSession);

        // 记录会话创建时间
        sessionCreationTime.put(sessionId, System.currentTimeMillis());

        // 生成CSRF Token
        String csrfToken = generateCSRFToken();
        csrfTokens.put(sessionId, csrfToken);

        // 清除登录失败记录
        String clientIP = getClientIPAddress(request);
        loginAttempts.remove(clientIP);
    }

    /**
     * 用户登出处理
     *
     * @param request HTTP请求对象
     */
    public static void onUserLogout(HttpServletRequest request) {
        HttpSession session = request.getSession(false);
        if (session != null) {
            String sessionId = session.getId();

            // 清理会话相关数据
            userSessions.remove(sessionId);
            sessionCreationTime.remove(sessionId);
            csrfTokens.remove(sessionId);
            session.invalidate();
        }
    }

    /**
     * 获取客户端IP地址（静态方法）
     *
     * @param request HTTP请求对象
     * @return 客户端IP地址
     */
    private static String getClientIPAddress(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("X-Real-IP");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
            if ("0:0:0:0:0:0:0:1".equals(ip)) {
                ip = "127.0.0.1";
            }
        }

        if (ip != null && ip.contains(",")) {
            ip = ip.split(",")[0];
        }

        return ip;
    }

    /**
     * 生成CSRF Token
     *
     * @return CSRF Token
     */
    private static String generateCSRFToken() {
        try {
            String uuid = UUID.randomUUID().toString();
            MessageDigest md = MessageDigest.getInstance("SHA-256");
            byte[] hash = md.digest(uuid.getBytes(StandardCharsets.UTF_8));
            StringBuilder hexString = new StringBuilder();
            for (byte b : hash) {
                String hex = Integer.toHexString(0xff & b);
                if (hex.length() == 1) {
                    hexString.append('0');
                }
                hexString.append(hex);
            }
            return hexString.toString();
        } catch (NoSuchAlgorithmException e) {
            return UUID.randomUUID().toString();
        }
    }

    /**
     * 记录登录失败
     *
     * @param username 用户名
     * @param request HTTP请求对象
     */
    public static void recordLoginFailure(String username, HttpServletRequest request) {
        String clientIP = getClientIPAddress(request);
        LoginAttempt attempt = loginAttempts.computeIfAbsent(clientIP,
                k -> new LoginAttempt(0, System.currentTimeMillis()));
        attempt.incrementAttempts();
        attempt.setLastAttemptTime(System.currentTimeMillis());
    }

    /**
     * 获取CSRF Token
     *
     * @param request HTTP请求对象
     * @return CSRF Token
     */
    public static String getCSRFToken(HttpServletRequest request) {
        HttpSession session = request.getSession(false);
        if (session != null) {
            String sessionId = session.getId();
            return csrfTokens.get(sessionId);
        }
        return null;
    }

    /**
     * 获取用户会话信息
     *
     * @param sessionId 会话ID
     * @return 用户会话信息
     */
    public static UserSession getUserSession(String sessionId) {
        return userSessions.get(sessionId);
    }

    /**
     * 获取在线用户数量
     *
     * @return 在线用户数量
     */
    public static int getOnlineUserCount() {
        return userSessions.size();
    }

    /**
     * 获取安全日志
     *
     * @param limit 返回记录数限制
     * @return 安全日志列表
     */
    public static List<SecurityLog> getSecurityLogs(int limit) {
        synchronized (securityLogs) {
            int size = securityLogs.size();
            int fromIndex = Math.max(0, size - limit);
            return new ArrayList<>(securityLogs.subList(fromIndex, size));
        }
    }

    /**
     * 获取请求统计信息
     *
     * @return 请求统计信息映射
     */
    public static Map<String, RequestStats> getRequestStats() {
        return new HashMap<>(requestStats);
    }

    /**
     * 获取API访问统计信息
     *
     * @return API访问统计信息映射
     */
    public static Map<String, ApiAccessStats> getApiAccessStats() {
        return new HashMap<>(apiAccessStats);
    }

    /**
     * 添加IP到黑名单
     *
     * @param ip IP地址
     */
    public static void addToBlacklist(String ip) {
        blacklistedIps.add(ip);
    }

    /**
     * 从黑名单移除IP
     *
     * @param ip IP地址
     */
    public static void removeFromBlacklist(String ip) {
        blacklistedIps.remove(ip);
    }

    /**
     * 获取黑名单IP列表
     *
     * @return 黑名单IP集合
     */
    public static Set<String> getBlacklistedIps() {
        return new HashSet<>(blacklistedIps);
    }

    /**
     * 添加敏感词
     *
     * @param word 敏感词
     */
    public static void addSensitiveWord(String word) {
        if (word != null && !word.trim().isEmpty()) {
            sensitiveWords.add(word.toLowerCase());
        }
    }

    /**
     * 移除敏感词
     *
     * @param word 敏感词
     */
    public static void removeSensitiveWord(String word) {
        if (word != null) {
            sensitiveWords.remove(word.toLowerCase());
        }
    }

    /**
     * 获取敏感词列表
     *
     * @return 敏感词集合
     */
    public static Set<String> getSensitiveWords() {
        return new HashSet<>(sensitiveWords);
    }

    /**
     * 获取系统统计信息
     *
     * @return 系统统计信息映射
     */
    public static Map<String, Object> getSystemStats() {
        Map<String, Object> stats = new HashMap<>();
        stats.put("onlineUsers", getOnlineUserCount());
        stats.put("blacklistedIps", blacklistedIps.size());
        stats.put("securityLogs", securityLogs.size());
        stats.put("sensitiveWords", sensitiveWords.size());
        stats.put("requestStats", requestStats.size());
        stats.put("apiAccessStats", apiAccessStats.size());
        return stats;
    }

    /**
     * 清理过期会话
     */
    public static void cleanupExpiredSessions() {
        long currentTime = System.currentTimeMillis();
        Iterator<Map.Entry<String, Long>> iterator = sessionCreationTime.entrySet().iterator();

        while (iterator.hasNext()) {
            Map.Entry<String, Long> entry = iterator.next();
            String sessionId = entry.getKey();
            Long creationTime = entry.getValue();

            if (currentTime - creationTime > SESSION_TIMEOUT) {
                // 清理过期会话数据
                userSessions.remove(sessionId);
                csrfTokens.remove(sessionId);
                iterator.remove();
            }
        }
    }

    /**
     * 重置统计信息
     */
    public static void resetStats() {
        requestStats.clear();
        apiAccessStats.clear();
        securityLogs.clear();
        loginAttempts.clear();
        uploadRecords.clear();
        rateLimits.clear();
    }

    // 内部类定义

    /**
     * 用户会话信息类
     */
    public static class UserSession {
        private User user;
        private long loginTime;
        private long lastAccessTime;

        public User getUser() {
            return user;
        }

        public void setUser(User user) {
            this.user = user;
        }

        public long getLoginTime() {
            return loginTime;
        }

        public void setLoginTime(long loginTime) {
            this.loginTime = loginTime;
        }

        public long getLastAccessTime() {
            return lastAccessTime;
        }

        public void setLastAccessTime(long lastAccessTime) {
            this.lastAccessTime = lastAccessTime;
        }
    }

    /**
     * 请求统计信息类
     */
    public static class RequestStats {
        private AtomicInteger count = new AtomicInteger(0);
        private long totalResponseTime = 0;
        private long maxResponseTime = 0;
        private long minResponseTime = Long.MAX_VALUE;

        public void incrementCount() {
            count.incrementAndGet();
        }

        public void addResponseTime(long responseTime) {
            synchronized (this) {
                totalResponseTime += responseTime;
                if (responseTime > maxResponseTime) {
                    maxResponseTime = responseTime;
                }
                if (responseTime < minResponseTime) {
                    minResponseTime = responseTime;
                }
            }
        }

        public int getCount() {
            return count.get();
        }

        public long getTotalResponseTime() {
            return totalResponseTime;
        }

        public long getMaxResponseTime() {
            return maxResponseTime;
        }

        public long getMinResponseTime() {
            return minResponseTime == Long.MAX_VALUE ? 0 : minResponseTime;
        }

        public double getAverageResponseTime() {
            int currentCount = count.get();
            return currentCount > 0 ? (double) totalResponseTime / currentCount : 0;
        }
    }

    /**
     * API访问统计信息类
     */
    public static class ApiAccessStats {
        private AtomicInteger accessCount = new AtomicInteger(0);
        private Set<String> clientIPs = ConcurrentHashMap.newKeySet();

        public void incrementAccessCount() {
            accessCount.incrementAndGet();
        }

        public void addClientIP(String ip) {
            clientIPs.add(ip);
        }

        public int getAccessCount() {
            return accessCount.get();
        }

        public int getUniqueClientCount() {
            return clientIPs.size();
        }

        public Set<String> getClientIPs() {
            return new HashSet<>(clientIPs);
        }
    }

    /**
     * 安全日志类
     */
    public static class SecurityLog {
        private long timestamp;
        private String ip;
        private String eventType;
        private String description;

        public long getTimestamp() {
            return timestamp;
        }

        public void setTimestamp(long timestamp) {
            this.timestamp = timestamp;
        }

        public String getIp() {
            return ip;
        }

        public void setIp(String ip) {
            this.ip = ip;
        }

        public String getEventType() {
            return eventType;
        }

        public void setEventType(String eventType) {
            this.eventType = eventType;
        }

        public String getDescription() {
            return description;
        }

        public void setDescription(String description) {
            this.description = description;
        }

        @Override
        public String toString() {
            return String.format("[%s] %s %s: %s",
                    new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(timestamp)),
                    ip, eventType, description);
        }
    }

    /**
     * 登录尝试记录类
     */
    public static class LoginAttempt {
        private int attempts;
        private long lastAttemptTime;

        public LoginAttempt(int attempts, long lastAttemptTime) {
            this.attempts = attempts;
            this.lastAttemptTime = lastAttemptTime;
        }

        public void incrementAttempts() {
            attempts++;
        }

        public int getAttempts() {
            return attempts;
        }

        public void setAttempts(int attempts) {
            this.attempts = attempts;
        }

        public long getLastAttemptTime() {
            return lastAttemptTime;
        }

        public void setLastAttemptTime(long lastAttemptTime) {
            this.lastAttemptTime = lastAttemptTime;
        }
    }

    /**
     * 上传记录类
     */
    public static class UploadRecord {
        private String fileName;
        private long fileSize;
        private String fileType;
        private String uploaderIP;
        private long uploadTime;
        private boolean isSafe;

        public String getFileName() {
            return fileName;
        }

        public void setFileName(String fileName) {
            this.fileName = fileName;
        }

        public long getFileSize() {
            return fileSize;
        }

        public void setFileSize(long fileSize) {
            this.fileSize = fileSize;
        }

        public String getFileType() {
            return fileType;
        }

        public void setFileType(String fileType) {
            this.fileType = fileType;
        }

        public String getUploaderIP() {
            return uploaderIP;
        }

        public void setUploaderIP(String uploaderIP) {
            this.uploaderIP = uploaderIP;
        }

        public long getUploadTime() {
            return uploadTime;
        }

        public void setUploadTime(long uploadTime) {
            this.uploadTime = uploadTime;
        }

        public boolean isSafe() {
            return isSafe;
        }

        public void setSafe(boolean safe) {
            isSafe = safe;
        }
    }

    /**
     * 速率限制信息类
     */
    public static class RateLimitInfo {
        private long lastRequestTime;
        private int requestCount;

        public RateLimitInfo(long lastRequestTime, int requestCount) {
            this.lastRequestTime = lastRequestTime;
            this.requestCount = requestCount;
        }

        public void increment() {
            requestCount++;
        }

        public void reset(long newTime) {
            lastRequestTime = newTime;
            requestCount = 1;
        }

        public long getLastRequestTime() {
            return lastRequestTime;
        }

        public int getRequestCount() {
            return requestCount;
        }
    }
}
